接口(interface)是一个非常强大的代码类型定义描述
接口的使用
有一个函数,这个函数接受一个 User 对象,然后返回这个 User 对象的 name 属性:
const getUserName = (user) => user.name
在我们自定义的 TypeScript 开发环境下这个是会报错的:
tsconfig.json 中 配置了 "noImplicitAny": true
我们必须用一种类型描述这个 user 参数,但是这个类型又不属于上一节介绍到的各种基本类型。
这个时候我们需要 interface 来描述这个类型:
interface User {
name: string
age: number
isMale: boolean
}
const getUserName = (user: User) => user.name
这个接口 User 描述了参数 user 的结构,当然接口不会去检查属性的顺序,只要相应的属性存在并且类型兼容即可。
可选属性
那么还有一个问题,当这个 user 属性可能没有 age 时怎么办?比如我们在前端处理表单的时候,年龄 age 这个字段本身是可选的,我们应该如何用接口描述这种情况?
我们可以用可选属性描述这种情况:
interface User {
name: string
age?: number
isMale: boolean
}
当我们看到代码提示的时候,这个 age 属性既可能是 number 类型也可能是 undefined 。
只读属性
还有一个问题,当我们确定 user 的性别之后就不允许就改了, interface 可以保证这一点吗?
利用 readonly 我们可以把一个属性变成只读性质,此后我们就无法对他进行修改
interface User {
name: string
age?: number
readonly isMale: boolean
}
一旦我们要修改只读属性,就会出现警告。
函数类型
那么接下来,如果这个 user 含有一个函数怎么办?
比如:
user.say = function(words: string) {
return 'hello world'
}
我们应该如何描述这种情况?一种是直接在 interface 内部描述函数:
interface User {
name: string
age?: number
readonly isMale: boolean
say: (words: string) => string
}
另一种方法,我们可以先用接口直接描述函数类型:
interface Say {
(words: string) : string
}
然后在 User 内使用:
interface User {
name: string
age?: number
readonly isMale: boolean
say: Say
}